#include "../facecat/stdafx.h"
#include "SecurityList.h"
#include "MainFrame.h"

void GridRowEx::onPaint(FCPaint *paint, const FCRect& clipRect, bool isAlternate){
    FCGrid *grid = getGrid();
    ArrayList<FCGridRow*> rows = grid->getSelectedRows();
    int rowsSize = rows.size();
    FCRect bounds = getBounds();
    int scrollH = 0, scrollV = 0;
    if (grid->getHScrollBar() != 0 && grid->getHScrollBar()->isVisible())
    {
        scrollH = grid->getHScrollBar()->getPos();
    }
    if (grid->getVScrollBar() != 0 && grid->getVScrollBar()->isVisible())
    {
        scrollV = grid->getVScrollBar()->getPos();
    }
    bounds.left = 1;
    bounds.top -= scrollV;
    bounds.right = bounds.right - bounds.left;
    bounds.bottom -= scrollV;
    if (rowsSize > 0)
    {
        bool selected = false;
        for(int i = 0; i < rows.size(); i++){
            if(rows.get(i) == this){
                selected = true;
                break;
            }
        }
        if (selected)
        {
            paint->fillRect(USERCOLOR219, bounds);
        }
        else
        {
            if (isAlternate)
            {
                if (MyColor::getStyle() == 0)
                {
                    paint->fillRect(FCColor::rgb(28, 28, 28), bounds);
                }
                else
                {
                    paint->fillRect(FCColor::rgb(240, 240, 240), bounds);
                }
            }
        }
    }
}

int FCGridNoCell::getInt(){
    return m_row->getIndex() + 1;
}

String FCGridNoCell::getText(){
    return FCTran::intToStr(getInt());
}

FCGridDoubleCellEx::FCGridDoubleCellEx(){
    setDigit(2);
}

void FCGridDoubleCellEx::onPaint(FCPaint paint, const FCRect& rect, const FCRect& clipRect, bool isAlternate){
    int clipW = clipRect.right - clipRect.left;
    int clipH = clipRect.bottom - clipRect.top;
    if (clipW > 0 && clipH > 0)
    {
        if (m_grid != 0 && m_row != 0 && m_column != 0)
        {
            String text = getPaintText();
            bool selected = false;
            if (m_grid->getSelectionMode() == FCGridSelectionMode_SelectCell)
            {
                ArrayList<FCGridCell*> selectedCells = m_grid->getSelectedCells();
                int selectedCellSize = selectedCells.size();
                for (int i = 0; i < selectedCellSize; i++)
                {
                    if (selectedCells.get(i) == this)
                    {
                        selected = true;
                        break;
                    }
                }
            }
            else if (m_grid->getSelectionMode() == FCGridSelectionMode_SelectFullColumn)
            {
                ArrayList<FCGridColumn*> selectedColumns = m_grid->getSelectedColumns();
                int selectedColumnsSize = selectedColumns.size();
                for (int i = 0; i < selectedColumnsSize; i++)
                {
                    if (selectedColumns.get(i) == m_column)
                    {
                        selected = true;
                        break;
                    }
                }
            }
            else if (m_grid->getSelectionMode() == FCGridSelectionMode_SelectFullRow)
            {
                ArrayList<FCGridRow*> selectedRows = m_grid->getSelectedRows();
                int selectedRowsSize = selectedRows.size();
                for (int i = 0; i < selectedRowsSize; i++)
                {
                    if (selectedRows.get(i) == m_row)
                    {
                        selected = true;
                        break;
                    }
                }
            }
            
            //获取颜色
            FCFont *font = 0;
            Long backColor = FCColor_None;
            Long textColor = FCColor_None;
            bool autoEllipsis = m_grid->autoEllipsis();
            FCGridRowStyle *rowStyle = m_grid->getRowStyle();
            if (isAlternate)
            {
                FCGridRowStyle *alternateRowStyle = m_grid->getAlternateRowStyle();
                if (alternateRowStyle != 0)
                {
                    rowStyle = alternateRowStyle;
                }
            }
            if (rowStyle != 0)
            {
                if (m_grid->getSelectionMode() != FCGridSelectionMode_SelectFullRow)
                {
                    if (backColor == FCColor_None)
                    {
                        if (selected)
                        {
                            backColor = rowStyle->getSelectedBackColor();
                        }
                        else if (m_row == m_grid->getHoveredRow())
                        {
                            backColor = rowStyle->getHoveredBackColor();
                        }
                        else
                        {
                            backColor = rowStyle->getBackColor();
                        }
                    }
                }
                if (font == 0)
                {
                    font = rowStyle->getFont();
                }
                if (textColor == FCColor_None)
                {
                    if (selected)
                    {
                        textColor = rowStyle->getSelectedTextColor();
                    }
                    else if (m_row == m_grid->getHoveredRow())
                    {
                        textColor = rowStyle->getHoveredTextColor();
                    }
                    else
                    {
                        textColor = rowStyle->getTextColor();
                    }
                }
            }
            //
            FCHorizontalAlign horizontalAlign = m_column->getCellAlign();
            //            if (m_backColor != FCColor_None)
            //            {
            //                backColor = m_backColor;
            //            }
            //            if (m_textColor != FCColor_None)
            //            {
            //                textColor = m_textColor;
            //            }
            FCRect backRect = rect;
            backRect.bottom -= 1;
            paint.fillRect(backColor, backRect);
            FCSize tSize = paint.textSize(text, font, -1);
            FCPoint tPoint = FCPoint({rect.left + 1, rect.top + clipH / 2 - tSize.cy / 2});
            int width = rect.right - rect.left;
            if (tSize.cx < width)
            {
                if (horizontalAlign == FCHorizontalAlign_Center)
                {
                    tPoint.x = rect.left + (rect.right - rect.left - tSize.cx) / 2;
                }
                else if (horizontalAlign == FCHorizontalAlign_Right)
                {
                    tPoint.x = rect.right - tSize.cx - 2;
                }
            }
            FCRect tRect = FCRect({tPoint.x, tPoint.y, tPoint.x + tSize.cx, tPoint.y + tSize.cy});
            if (autoEllipsis && (tRect.right > clipRect.right || tRect.bottom > clipRect.bottom))
            {
                if (tRect.right > clipRect.right)
                {
                    tRect.right = clipRect.right;
                }
                if (tRect.bottom > clipRect.bottom)
                {
                    tRect.bottom = clipRect.bottom;
                }
                paint.drawTextAutoEllipsis(text, textColor, font, tRect);
            }
            else
            {
                paint.drawText(text, textColor, font, tRect, -1);
            }
        }
    }
}

String FCGridUnitDoubleCell::getPaintText(){
    double value = getDouble();
    if (value >= 10000000)
    {
        return FCTran::getValueByDigit(value / 10000000, 2) + L"亿";
    }
    else if (value >= 10000)
    {
        return FCTran::getValueByDigit(value / 10000, 2) + L"万";
    }
    else
    {
        return FCTran::getValueByDigit(value, 2);
    }
}


String FCGridUnitLongCell::getPaintText()
{
    return FCTran::longToStr((long)getDouble()) + L"亿";
}


String FCGridPECell::getPaintText(){
    double value = getDouble();
    if (value < 0)
    {
        return L"亏损";
    }
    else
    {
        return FCTran::getValueByDigit(value, 2);
    }
}

SecurityList::SecurityList(){
    m_requestID = -1;
    m_menu = 0;
    m_firstAdd = true;
    m_isKeyDown = false;
    m_isFirstOrSecond = 0;
}

void SecurityList::bindCodes(ArrayList<Security*> codes)
{
    if(m_rows.size() > 0){
        m_rowsMap.clear();
        clearRows();
        update();
        getSelectedRows().clear();
    }
    beginUpdate();
    for(int i = 0; i < codes.size(); i++){
        Security *security = codes.get(i);
        if (security->m_name.length() > 0)
        {
            GridRowEx *row = new GridRowEx;
            addRow(row);
            row->setHeight(25);
            String showCode = security->m_code.substr(0, security->m_code.find(L"."));
            row->setTag(security->m_code);
            row->addCell(L"colP0", new FCGridNoCell());
            row->addCell(L"colP1", new FCGridStringCell(showCode));
            row->addCell(L"colP2", new FCGridStringCell(security->m_name));
            FCGridDoubleCellEx *priceCell = new FCGridDoubleCellEx;
            priceCell->m_underLine = true;
            row->addCell(L"colP3", priceCell);
            row->addCell(L"colP4", new FCGridPercentCell());
            row->addCell(L"colP5", new FCGridDoubleCellEx());
            row->addCell(L"colP9", new FCGridUnitDoubleCell());
            row->addCell(L"colP10", new FCGridUnitDoubleCell());
            row->addCell(L"colP11", new FCGridDoubleCellEx());
            row->addCell(L"colP12", new FCGridPECell());
            row->addCell(L"colP13", new FCGridPercentCell());
            row->addCell(L"colP14", new FCGridPercentCell());
            row->addCell(L"colP15", new FCGridUnitLongCell());
            row->addCell(L"colP16", new FCGridUnitLongCell());
            row->addCell(L"colP17", new FCGridStringCell());
            row->addCell(L"colP18", new FCGridDoubleCellEx());
            row->addCell(L"colP19", new FCGridDoubleCellEx());
            row->addCell(L"colP20", new FCGridDoubleCellEx());
            row->addCell(L"colP21", new FCGridPercentCell());
            row->addCell(L"colP22", new FCGridPercentCell());
            row->addCell(L"colP23", new FCGridPercentCell());
            row->addCell(L"colP24", new FCGridStringCell(security->m_code));
            m_rowsMap.put(security->m_code, row);
            //            m_rowsMap.get(security->m_code) = row;
            for (int i = 0; i < row->m_cells.size(); i++)
            {
                FCGridCell *cell = row->m_cells.get(i);
                FCGridCellStyle style;
                if (i == 0 || i == 2)
                {
                    style.m_textColor = FCColor::rgb(194, 151, 18);
                }
                else
                {
                    style.m_textColor = FCColor::rgb(190, 190, 235);
                }
                cell->setStyle(&style);
            }
        }
    }
    endUpdate();
}

void SecurityList::callInvokeEvent(String eventName, Object sender, Object args, Object invoke){
    if (args != 0)
    {
        FCMessage *message = (FCMessage*)args;
        if (message != 0)
        {
//            PriceDataServiceClient.SERVICEID
            if (message->m_serviceID == 10004)
            {
                if (message->m_functionID == FUNCTION_NEWDATA)
                {
                    HashMap<String, int> columnsMap;
                    for (int i = 0; i < m_columns.size(); i++)
                    {
                        FCGridColumn *gridColumn = m_columns.get(i);
                        columnsMap.put(gridColumn->getName(), gridColumn->getIndex());
                    }
                    ArrayList<int> columnIndex;
                    columnIndex.add(columnsMap.get(L"colP3"));
                    columnIndex.add(columnsMap.get(L"colP4"));
                    columnIndex.add(columnsMap.get(L"colP5"));
                    columnIndex.add(columnsMap.get(L"colP9"));
                    columnIndex.add(columnsMap.get(L"colP10"));
                    columnIndex.add(columnsMap.get(L"colP11"));
                    columnIndex.add(columnsMap.get(L"colP12"));
                    columnIndex.add(columnsMap.get(L"colP13"));
                    columnIndex.add(columnsMap.get(L"colP14"));
                    columnIndex.add(columnsMap.get(L"colP15"));
                    columnIndex.add(columnsMap.get(L"colP16"));
                    columnIndex.add(columnsMap.get(L"colP17"));
                    columnIndex.add(columnsMap.get(L"colP18"));
                    columnIndex.add(columnsMap.get(L"colP19"));
                    columnIndex.add(columnsMap.get(L"colP20"));
                    columnIndex.add(columnsMap.get(L"colP21"));
                    columnIndex.add(columnsMap.get(L"colP22"));
                    columnIndex.add(columnsMap.get(L"colP23"));
                    columnIndex.add(columnsMap.get(L"colP24"));
                    ArrayList<PriceData> priceDatas = PriceDataServiceClient::getPriceDatas(message->m_body, message->m_bodyLength);
                    for (int i = 0; i < priceDatas.size(); i++)
                    {
                        PriceData priceData = priceDatas.get(i);
                        String code = priceData.m_code;
                        if (m_rowsMap.containsKey(code))
                        {
                            FCGridRow *row = m_rowsMap.get(code);
                            double lastClose = priceData.m_lastClose;
                            double diff = 0, diffRange = 0;
                            double close = priceData.m_close;
                            if (close > 0)
                            {
                                diff = close - priceData.m_lastClose;
                            }
                            if (close > 0 && priceData.m_lastClose != 0)
                            {
                                diffRange = diff / priceData.m_lastClose;
                            }
                            FCGridCell *cell3 = row->getCell(columnIndex.get(0));
                            cell3->setDouble(close);

                            if (close > 0 && close == priceData.m_upperLimit)
                            {
                                cell3->m_style->m_backColor = FCColor::rgb(255, 82, 82);
                                cell3->m_style->m_textColor = FCColor_Back;
                            }
                            else if (close > 0 && close == priceData.m_lowerLimit)
                            {
                                cell3->m_style->m_backColor = FCColor::rgb(82, 255, 82);
                                cell3->m_style->m_textColor = FCColor_Back;
                            }
                            else
                            {
                                cell3->m_style->m_backColor = FCColor_None;
                                cell3->m_style->m_textColor = FCDraw::getPriceColor(close, lastClose);
                            }

                            FCGridCell *cell4 = row->getCell(columnIndex.get(1));
                            cell4->setDouble(diffRange);
                            cell4->m_style->m_textColor = FCDraw::getPriceColor(close, lastClose);

                            FCGridCell *cell5 = row->getCell(columnIndex.get(2));
                            cell5->setDouble(diff);
                            cell5->m_style->m_textColor = FCDraw::getPriceColor(close, lastClose);

                            FCGridCell *cell9 = row->getCell(columnIndex.get(3));
                            cell9->setDouble(priceData.m_volume / 100);

                            FCGridCell *cell10 = row->getCell(columnIndex.get(4));
                            cell10->setDouble(priceData.m_amount);

                            FCGridCell *cell11 = row->getCell(columnIndex.get(5));
                            cell11->setDouble(priceData.m_ratio);

                            FCGridCell *cell12 = row->getCell(columnIndex.get(6));
                            cell12->setDouble(priceData.m_pe);

                            double range = 0;
                            if (lastClose != 0)
                            {
                                range = (priceData.m_high - lastClose) / lastClose - (priceData.m_low - lastClose) / lastClose;
                            }
                            FCGridCell *cell13 = row->getCell(columnIndex.get(7));
                            cell13->setDouble(range);
                            FCGridCell *cell14 = row->getCell(columnIndex.get(8));
                            cell14->setDouble(priceData.m_turnoverRate / 100);
                            FCGridCell *cell15 = row->getCell(columnIndex.get(9));
                            cell15->setDouble(priceData.m_marketValue);
                            FCGridCell *cell16 = row->getCell(columnIndex.get(10));
                            cell16->setDouble(priceData.m_flow);
                            FCGridCell *cell17 = row->getCell(columnIndex.get(11));
//                            if (DataCenter::getSecurityService()->m_securitiesMap.ContainsKey(code))
                            {
                                cell17->setString(DataCenter::getSecurityService()->m_securitiesMap.get(code)->m_block);
                            }
                            FCGridCell *cell18 = row->getCell(columnIndex.get(12));
                            cell18->setDouble(priceData.m_upperLimit);
                            cell18->m_style->m_textColor = FCDraw::getPriceColor(priceData.m_upperLimit, lastClose);
                            FCGridCell *cell19 = row->getCell(columnIndex.get(13));
                            cell19->setDouble(priceData.m_lowerLimit);
                            cell19->m_style->m_textColor = FCDraw::getPriceColor(priceData.m_lowerLimit, lastClose);

                        }
                    }
                    invalidate();
                }
            }
            delete message->m_body;
            delete message;
        }
    }
}

void SecurityList::callListenerMessageEvent(Object sender, FCMessage *message, Object invoke){
    FCMessage *copyMessage = new FCMessage;
    copyMessage->copy(message);
    char *str = new char[copyMessage->m_bodyLength];
    for(int i = 0; i < copyMessage->m_bodyLength; i++){
        str[i] = message->m_body[i];
    }
    copyMessage->m_body = str;
    this->invoke(copyMessage);
}

void SecurityList::onTouchDown(FCTouchInfo touchInfo){
    callTouchEvents(L"ontouchdown", touchInfo);
    if (!allowPreviewsEvent())
    {
        onDragScrollStart();
    }
    m_clickLeftOrRight = touchInfo.m_firstTouch;
    touchEvent(touchInfo, 1);
}

void SecurityList::onAdd(){
    FCGrid::onAdd();
    if (m_firstAdd)
    {
        m_firstAdd = false;
        addEvent((FCInvokeEventCallBack*)this, L"oninvoke", this);
        getVScrollBar()->setLineSize(25);
    }
}

void SecurityList::searchCodes(ArrayList<Security*> securities){
    if (m_requestID != -1)
    {
        DataCenter::getPriceDataServiceClient()->removeListener(m_requestID);
        DataCenter::getPriceDataServiceClient()->unSubCodes(m_requestID);
    }
    bindCodes(securities);
    m_requestID = FCClientService::getRequestID();
    DataCenter::getPriceDataServiceClient()->addListener(m_requestID, this, this);
    StringBuilder sb;
    for (int i = 0; i < securities.size(); i++)
    {
        Security *security = securities.get(i);
        sb.append(security->m_code + L",");
    }
    String codes = sb.toString();
    if (codes.find(L",") == codes.length() - 1)
    {
        codes = codes.substr(0, codes.length() - 1);
    }
    DataCenter::getPriceDataServiceClient()->subCodes(m_requestID, codes);
}

void SecurityList::firstSearchCode(){
    ArrayList<Security*> securities;
    securities = DataCenter::getSecurityService()->m_securities;
    searchCodes(securities);
}
//
void SecurityList::onKeyDown(char key){
    FCGrid::onKeyDown(key);
    m_isKeyDown = true;
}

void SecurityList::onKeyUp(char key){
    FCGrid::onKeyUp(key);
    m_isKeyDown = false;
    if (m_searchCode.length() > 0)
    {
        MainFrame::getMainFrame()->searchCode(m_searchCode);
    }
    m_searchCode = L"";
}

void SecurityList::onSelectedRowsChanged(){
    FCGrid::onSelectedRowsChanged();
    //    try
    //    {
    if (m_clickLeftOrRight)
    {
        if (getSelectedRows().get(0)->m_cells.size() > 0)
        {
            String code = getSelectedRows().get(0)->getCell(L"colP24")->getString();
            if (m_isKeyDown)
            {
                m_searchCode = code;
            }
            else
            {
                MainFrame::getMainFrame()->searchCode(code);
            }
        }
    }
}

void SecurityList::fullScreen(){
}

void SecurityList::callMenuItemTouchEvent(String eventName, Object sender, FCMenuItem item, FCTouchInfo touchInfo, Object invoke){
    if (item.getText() == L"进入全屏" || item.getText() == L"退出全屏")
    {
        fullScreen();
    }
}

